package com.tj.jinzao.widgets;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.drawable.Drawable;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TextView;

import com.tj.jinzao.common.Constant;
import com.tj.jinzao.utils.Utils;

import java.util.ArrayList;
import java.util.List;

/**
 * 滑轮view
 * Created by wjy on 2016/7/13.
 */
public class WheelView extends ScrollView {
    public static final String TAG = WheelView.class.getSimpleName();

    private LinearLayout mLinearLayout;
    private List<String> mItems;

    public static final int OFF_SET_DEFAULT = 1;
    private int mOffset = OFF_SET_DEFAULT; // 偏移量（需要在最前面和最后面补全）

    private int mDisplayItemCount; // 每页显示的数量

    private int mSelectedIndex = 1;

    private int mInitialY;

    private Runnable mScrollerTask;
    public static final int CHECK_TIME = 50;


    private int mItemHeight;

    private OnWheelViewListener mWheelViewListener;

    public WheelView(Context context) {
        super(context);
        init(context);
    }

    public WheelView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public WheelView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(context);
    }

    public void setItems(List<String> list) {
        if (null == mItems) {
            mItems = new ArrayList();
        }
        mItems.clear();
        mItems.addAll(list);

        // 前面和后面补全
        for (int i = 0; i < mOffset; i++) {
            mItems.add(0, "");
            mItems.add("");
        }

        initData();

    }


    private void init(Context context) {
        this.setVerticalScrollBarEnabled(false);

        mLinearLayout = new LinearLayout(context);
        mLinearLayout.setOrientation(LinearLayout.VERTICAL);
        this.addView(mLinearLayout);

        mScrollerTask = new Runnable() {

            public void run() {

                int newY = getScrollY();
                if (mInitialY - newY == 0) { // stopped
                    final int remainder = mInitialY % mItemHeight;
                    final int divided = mInitialY / mItemHeight;
                    if (remainder == 0) {
                        mSelectedIndex = divided + mOffset;
                        onSelectedCallBack();
                    } else {
                        if (remainder > mItemHeight / 2) {
                            WheelView.this.post(new Runnable() {
                                @Override
                                public void run() {
                                    WheelView.this.smoothScrollTo(0, mInitialY - remainder + mItemHeight);
                                    mSelectedIndex = divided + mOffset + 1;
                                    onSelectedCallBack();
                                }
                            });
                        } else {
                            WheelView.this.post(new Runnable() {
                                @Override
                                public void run() {
                                    WheelView.this.smoothScrollTo(0, mInitialY - remainder);
                                    mSelectedIndex = divided + mOffset;
                                    onSelectedCallBack();
                                }
                            });
                        }


                    }


                } else {
                    mInitialY = getScrollY();
                    WheelView.this.postDelayed(mScrollerTask, CHECK_TIME);
                }
            }
        };


    }


    public void startScrollerTask() {

        mInitialY = getScrollY();
        this.postDelayed(mScrollerTask, CHECK_TIME);
    }

    private void initData() {
        mDisplayItemCount = mOffset * 2 + 1;
        mLinearLayout.removeAllViews();
        for (String item : mItems) {
            mLinearLayout.addView(createView(item));
        }
        setSelection(0);
        refreshItemView(0);
    }

    private TextView createView(String item) {
        TextView tv = new TextView(getContext());
        tv.setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
        tv.setTextSize(TypedValue.COMPLEX_UNIT_SP, 20);
        tv.setText(item);
        tv.setGravity(Gravity.CENTER);
        int padding = Utils.dpToPx(15, getResources());
        tv.setPadding(padding, padding, padding, padding);
        if (0 == mItemHeight) {
            mItemHeight = getViewMeasuredHeight(tv);
            mLinearLayout.setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, mItemHeight * mDisplayItemCount));
            LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) this.getLayoutParams();
            this.setLayoutParams(new LinearLayout.LayoutParams(lp.width, mItemHeight * mDisplayItemCount));
        }
        return tv;
    }


    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        super.onScrollChanged(l, t, oldl, oldt);
        refreshItemView(t);

        if (t > oldt) {
//            Log.d(TAG, "向下滚动");
            mScrollDirection = SCROLL_DIRECTION_DOWN;
        } else {
//            Log.d(TAG, "向上滚动");
            mScrollDirection = SCROLL_DIRECTION_UP;

        }


    }

    private void refreshItemView(int y) {
        int position = y / mItemHeight + mOffset;
        int remainder = y % mItemHeight;
        int divided = y / mItemHeight;

        if (remainder == 0) {
            position = divided + mOffset;
        } else {
            if (remainder > mItemHeight / 2) {
                position = divided + mOffset + 1;
            }
        }

        int childSize = mLinearLayout.getChildCount();
        for (int i = 0; i < childSize; i++) {
            TextView itemView = (TextView) mLinearLayout.getChildAt(i);
            itemView.setLines(1);
            if (null == itemView) {
                return;
            }
            if (position == i) {
                itemView.setTextColor(Color.parseColor("#FF535671"));
            } else {
                itemView.setTextColor(Color.parseColor("#FFB9BDD2"));
            }
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        setBackGround();
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        setBackGround();
    }

    private void setBackGround() {
        setBackground(new Drawable() {
            @Override
            public void draw(@NonNull Canvas canvas) {
                if (null == mPaint) {
                    mPaint = new Paint();
                    mPaint.setColor(Color.parseColor("#FFE3E5ED"));
                    mPaint.setStrokeWidth(2 * Constant.SCALE_X);
                }
                canvas.drawLine(0, getHeight() / 2 - getHeight() / 6, getWidth(), getHeight() / 2 - getHeight() / 6, mPaint);
                canvas.drawLine(0, getHeight() / 2 + getHeight() / 6, getWidth(), getHeight() / 2 + getHeight() / 6, mPaint);
            }

            @Override
            public void setAlpha(int alpha) {

            }

            @Override
            public void setColorFilter(@Nullable ColorFilter colorFilter) {

            }

            @Override
            public int getOpacity() {
                return PixelFormat.UNKNOWN;
            }
        });
    }

    private Paint mPaint;

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

    }

    private int mScrollDirection = -1;
    private static final int SCROLL_DIRECTION_UP = 0;
    private static final int SCROLL_DIRECTION_DOWN = 1;

    /**
     * 选中回调
     */
    private void onSelectedCallBack() {
        if (null != mWheelViewListener) {
            if (mSelectedIndex >= mItems.size() - mOffset * 2)
                mSelectedIndex = mItems.size() - mOffset * 2;
            mWheelViewListener.onSelected(mSelectedIndex, mItems.get(mSelectedIndex));
        }

    }

    public void setSelection(int position) {
        final int p = position;
        mSelectedIndex = p + mOffset;
        if (mSelectedIndex >= mItems.size() - mOffset * 2)
            mSelectedIndex = mItems.size() - mOffset * 2;
        this.post(new Runnable() {
            @Override
            public void run() {
                WheelView.this.smoothScrollTo(0, p * mItemHeight);
            }
        });

    }

    @Override
    public void fling(int velocityY) {
        super.fling(velocityY / 3);
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        if (ev.getAction() == MotionEvent.ACTION_UP) {

            startScrollerTask();
        }
        return super.onTouchEvent(ev);
    }


    public OnWheelViewListener getOnWheelViewListener() {
        return mWheelViewListener;
    }

    public void setOnWheelViewListener(OnWheelViewListener onWheelViewListener) {
        this.mWheelViewListener = onWheelViewListener;
    }


    private int getViewMeasuredHeight(View view) {
        int width = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
        int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
        view.measure(width, expandSpec);
        return view.getMeasuredHeight();
    }

    public interface OnWheelViewListener {
        void onSelected(int selectedIndex, String item);
    }

}
